package com.gitee.wsl.mathematics.matrix.mat4.ext

import com.gitee.wsl.mathematics.matrix.ext.setIdentity
import com.gitee.wsl.mathematics.matrix.mat4.Matrix4
import com.gitee.wsl.mathematics.matrix.mat4.MutableMatrix4
import com.gitee.wsl.mathematics.vector.vec2.Vec2f
import com.gitee.wsl.mathematics.vector.vec2.Vector2
import com.gitee.wsl.mathematics.vector.vec3.MutableVector3
import com.gitee.wsl.mathematics.vector.vec3.Vector3
import com.gitee.wsl.mathematics.vector.vec4.Vector4

/**
 * Note: You must clone or copy the values of this [Vec2f] due to the values of this referenced
 * [Vec2f] will change.
 *
 * @return this matrix's translation component
 */
val <T:Number,V: Matrix4<T, V, R>,R: Vector4<T, R>> Matrix4<T, V, R>.translate get() = createVec3(m03, m13,m23)


fun<T:Number> MutableMatrix4<T, *, *>.setTranslate(x: T, y: T, z:T){
    setIdentity()
    m03 = x
    m13 = y
    m23 = z
}

fun<T:Number> MutableMatrix4<T, *, *>.setTranslate(vec2: Vector2<T, *>) = setTranslate(vec2.x, vec2.y,zero)

fun<T:Number> MutableMatrix4<T, *, *>.setTranslate(vec3: Vector3<T, *>) = setTranslate(vec3.x, vec3.y,vec3.z)

fun<T:Number> MutableMatrix4<T, *, *>.setToTranslateAndScaling(
    tx: T, ty: T, tz: T,
    sx: T, sy: T, sz: T
){
    setIdentity()
    m03 = tx
    m13 = ty
    m23 = tz
    m00 = sx
    m11 = sy
    m22 = sz
}

fun<T:Number> MutableMatrix4<T, *, *>.setToTranslateAndScaling(translation: Vector3<T,*>, scale: Vector3<T,*>) =
    setToTranslateAndScaling(
        translation.x, translation.y, translation.z,
        scale.x, scale.y, scale.z
    )


/**
 * Inplace operation: Adds the given translation [tx], [ty], [tz] transform to this matrix.
 */
fun<T:Number> MutableMatrix4<T, *, *>.translate(tx: T, ty: T, tz:T){
    m03 += m00 * tx + m01 * ty + m02 * tz
    m13 += m10 * tx + m11 * ty + m12 * tz
    m23 += m20 * tx + m21 * ty + m22 * tz
}

fun<T:Number> MutableMatrix4<T, *, *>.translate(vec2: Vector2<T, *>) = translate(vec2.x, vec2.y,zero)

fun<T:Number> MutableMatrix4<T, *, *>.translate(vec3: Vector3<T, *>) = translate(vec3.x, vec3.y,vec3.z)
